import unittest
from utils import simple_connect, simple_new_connection

from smalltable import simpleclient
from smalltable.simpleclient import RESERVED_FLAG_PROXY_COMMAND, MemcachedOutOfMemory, MemcachedKeyNotFoundError, MemcachedUnknownCommand, PROXY_CMD_GET_CONFIG, PROXY_CMD_SET_CONFIG, PROXY_CMD_STOP, PROXY_CMD_START, OP_GET
import struct
import socket

class TestGlobal(unittest.TestCase):
    @simple_connect
    def test_unknown_server_command(self, mc):
        self.assertRaises(simpleclient.MemcachedUnknownCommand,
            mc._custom_command, opcode=0x99, key='a', value='b' )

    @simple_connect
    def test_unknown_proxy_command(self, mc):
        self.assertRaises(MemcachedUnknownCommand,
            mc._custom_command, opcode=0x99, key='a', value='b', reserved=RESERVED_FLAG_PROXY_COMMAND )

    @simple_connect
    def test_cmd_get_config(self, mc):
        c = mc._custom_command(opcode=PROXY_CMD_GET_CONFIG, reserved=RESERVED_FLAG_PROXY_COMMAND)
        self.assertEqual(c.startswith("# This file is automatically generated. Do not edit"), True)
        self.assertEqual("#Created on " in c, True)
        self.assertEqual("\nproxy" in c, True)
        self.assertEqual("\nserver" in c, True)

    @simple_connect
    def test_cmd_set_config(self, mc):
        prev = mc._custom_command(opcode=PROXY_CMD_GET_CONFIG, reserved=RESERVED_FLAG_PROXY_COMMAND)
        new = '''# This file is automatically generated. Do not edit.
#Created on Fri Jan 29 19:01:56 2010, debian

proxy\t127.0.0.2:11211

server\t127.0.0.3:11222, 10, 
server\t127.0.0.4:11222, 10, DADE
''' # whitespace here is important

        self.assertRaises(MemcachedKeyNotFoundError, mc._custom_command,
            opcode=PROXY_CMD_SET_CONFIG, reserved=RESERVED_FLAG_PROXY_COMMAND, value=new)


        mc._custom_command(opcode=PROXY_CMD_STOP, reserved=RESERVED_FLAG_PROXY_COMMAND)
        mc._custom_command(opcode=PROXY_CMD_SET_CONFIG, reserved=RESERVED_FLAG_PROXY_COMMAND, value=new)
        mc._custom_command(opcode=PROXY_CMD_START, reserved=RESERVED_FLAG_PROXY_COMMAND)

        curr = mc._custom_command(opcode=PROXY_CMD_GET_CONFIG, reserved=RESERVED_FLAG_PROXY_COMMAND)
        self.assertEqual(new.split('\n', 2)[2], curr.split('\n', 2)[2])

        mc._custom_command(opcode=PROXY_CMD_STOP, reserved=RESERVED_FLAG_PROXY_COMMAND)
        mc._custom_command(opcode=PROXY_CMD_SET_CONFIG, reserved=RESERVED_FLAG_PROXY_COMMAND, value=prev)
        mc._custom_command(opcode=PROXY_CMD_START, reserved=RESERVED_FLAG_PROXY_COMMAND)
        curr = mc._custom_command(opcode=PROXY_CMD_GET_CONFIG, reserved=RESERVED_FLAG_PROXY_COMMAND)
        self.assertEqual(prev.split('\n', 2)[2], curr.split('\n', 2)[2])

    @simple_connect
    def test_cmd_stop_start(self, mc):
        nc = simple_new_connection()
        try:
            nc.get('a') # connect to server
        except MemcachedOutOfMemory:
            pass
        sd = nc.conn.sd
        sd.settimeout(0.001)
        header = struct.pack('!BBHBBHIIQ',
            0x80, OP_GET, 1,
            0, 0x00, 0x00,
            1,
            0xDEAD,
            0x00)
        sd.sendall(header + 'a')
        r = sd.recv(4096)
        self.assertEqual( r.startswith('\x81\x00\x00\x00\x00\x00\x00'), True)

        mc._custom_command(opcode=PROXY_CMD_STOP, reserved=RESERVED_FLAG_PROXY_COMMAND)

        sd.sendall(header + 'a')
        self.assertRaises(socket.timeout, sd.recv, 4096)

        mc._custom_command(opcode=PROXY_CMD_START, reserved=RESERVED_FLAG_PROXY_COMMAND)

        r = sd.recv(4096)
        self.assertNotEqual( r, '' )


